﻿/*
 * This is a .NET port of the Apache Chemistry QueryParser. http://chemistry.apache.org/
 * The conversion was performed by Brügmann Software GmbH. Programmer: Björn Kremer.
 *
 * This project is still under the original Apache License: 
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Antlr.Runtime;

namespace QueryParser
{
   public class QueryUtil
   {
      private CmisQueryWalker walker;

      // convenience method because everybody needs this piece of code
      //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
      //ORIGINAL LINE: public static CmisQueryWalker getWalker(String statement) throws org.antlr.runtime.RecognitionException
      public static CmisQueryWalker getWalker(string statement)
      {

         Antlr.Runtime.ANTLRStringStream input = new Antlr.Runtime.ANTLRStringStream(statement);
         CmisQlStrictLexer lexer = new CmisQlStrictLexer(input);
         Antlr.Runtime.CommonTokenStream tokens = new Antlr.Runtime.CommonTokenStream(lexer);
         CmisQlStrictParser parser = new CmisQlStrictParser(tokens);
         Antlr.Runtime.Tree.CommonTree parserTree; // the ANTLR tree after parsing phase

         AstParserRuleReturnScope<object, IToken> parsedStatement = parser.query();
         if (parser.hasErrors())
         {
            throw new System.ArgumentException(parser.getErrorMessages());
         }
         else if (tokens.Index != tokens.Count -1)
         {
            throw new System.ArgumentException("Query String has illegal tokens after end of statement: " + tokens.Get(tokens.Index));
         }

         parserTree = (Antlr.Runtime.Tree.CommonTree)parsedStatement.Tree;

         Antlr.Runtime.Tree.CommonTreeNodeStream nodes = new Antlr.Runtime.Tree.CommonTreeNodeStream(parserTree);
         nodes.TokenStream = tokens;
         CmisQueryWalker walker = new CmisQueryWalker(nodes);
         return walker;
      }

      //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
      //ORIGINAL LINE: public CmisQueryWalker traverseStatement(String statement, QueryObject queryObj, PredicateWalkerBase pw) throws java.io.UnsupportedEncodingException, java.io.IOException, org.antlr.runtime.RecognitionException
      public virtual CmisQueryWalker traverseStatement(string statement, QueryObject queryObj, PredicateWalkerBase pw)
      {
         walker = getWalker(statement);
         walker.query(queryObj, pw);
         walker.getWherePredicateTree();
         return walker;
      }

      public virtual CmisQueryWalker traverseStatementAndCatchExc(string statement, QueryObject queryObj, PredicateWalkerBase pw)
      {
         try
         {
            return traverseStatement(statement, queryObj, pw);
         }
         catch (RecognitionException e)
         {
            string errorMsg = queryObj.ErrorMessage;
            throw new System.ArgumentException("Walking of statement failed with RecognitionException error: \n   " + errorMsg);
         }
         catch (Exception e)
         {
            throw new System.ArgumentException("Walking of statement failed with exception: \n   " + e);
         }
      }

      public virtual string getErrorMessage(RecognitionException e)
      {
         if (null == walker)
         {
            return e.ToString();
         }
         else
         {
            return getErrorMessage(walker, e);
         }
      }

      private static string getErrorMessage(BaseRecognizer recognizer, RecognitionException e)
      {
         string[] tokenNames = recognizer.TokenNames;
         // String hdr = walker.getErrorHeader(e);
         string hdr = "Line " + e.Line + ":" + e.CharPositionInLine;
         string msg = recognizer.GetErrorMessage(e, tokenNames);
         return hdr + " " + msg;
      }

   }
}
